﻿using Hydrogen.ULib.DataStructure;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;

namespace Hydrogen.MarkovChain.SolidMap2DScene
{
    public class SolidCache : SolidCacheBase
    {
        private Dictionary<SolidType, SolidCacheItem> _dir;

        public SolidCache()
        {
            this._dir = new Dictionary<SolidType, SolidCacheItem>();
        }

        public override void SetSolid(SolidType solid, int x, int y)
        {
            if (!this._dir.TryGetValue(solid, out var item))
            {
                item = new SolidCacheItem(solid);
                this._dir[solid] = item;
            }

            item.SetPos(x, y);
        }

        public override void RemoveSolid(SolidType solid, int x, int y)
        {
            if (!this._dir.TryGetValue(solid, out var item)) return;
            item.RemovePos(x, y);
        }

        public override void Clear()
        {
            foreach (var item in this._dir)
            {
                item.Value.Clear();
            }

            this._dir.Clear();
        }

        public override List<Vector2Int> GetSolidPos(SolidType solid, bool random)
        {
            if (!this._dir.TryGetValue(solid, out var item)) return new List<Vector2Int>();
            return item.GetPos(random);
        }

        public class SolidCacheItem
        {
            public SolidType solid { get; }
            private TwoDimensionDic<int, int, bool> _pos;

            public SolidCacheItem(SolidType solid)
            {
                this.solid = solid;
                _pos = new TwoDimensionDic<int, int, bool>();
            }

            /// <summary>
            /// 写入位置
            /// </summary>
            /// <param name="x"></param>
            /// <param name="y"></param>
            public void SetPos(int x, int y)
            {
                this._pos[x, y] = true;
            }
            public void RemovePos(int x, int y)
            {
                this._pos.Remove(x, y);
            }

            /// <summary>
            /// 是否存在这个位置
            /// </summary>
            /// <param name="x"></param>
            /// <param name="y"></param>
            /// <returns></returns>
            public bool HasPos(int x, int y)
            {
                return this._pos.ContainsKey(x, y);
            }

            /// <summary>
            /// 获取所有位置
            /// </summary>
            /// <param name="random">是否打乱顺序</param>
            public List<Vector2Int> GetPos(bool random)
            {
                List<Vector2Int> result = new List<Vector2Int>();

                this._pos.Foreach((x, y, b) =>
                {
                    result.Add(new Vector2Int(x, y));
                });

                if (random)
                    Utils.RandomArray(result);

                return result;
            }

            public void Clear()
            {
                this._pos.Clear();
            }
        }
    }

}
